import os
import zipfile
import tarfile
import argparse
import subprocess


class AcceptanceTool(object):
    def devkit_acceptance_report(self, compressed_report_package):
        if not os.path.exists(compressed_report_package):
            print("Enter a correct report package.")
            return
        file_ext = os.path.splitext(compressed_report_package)[1].lower()
        if file_ext not in (".zip", ".gz", ".bz2"):
            print("Please use the compressed package in the following format:.zip、.gz、.bz2")
            return
        decompress = {".zip": decompress_zip, ".gz": decompress_gz_bz, ".bz2": decompress_gz_bz}
        current_path = os.getcwd()
        print("Starting decompression...")
        file_names = decompress.get(file_ext)(compressed_report_package)
        command_line_html = {"64-bit Running Mode Check Report": "64位运行模式检查",
                             "Static Check Report": "内存一致性检查",
                             "Vectorization Check Report": "向量化检查",
                             "Software Porting Assessment Report": "软件迁移评估",
                             "Byte Alignment Check Report": "字节对齐检查",
                             "Source Code Porting Report": "源码迁移", "Compatibility_Application": "云测工具",
                             "Build Affinity Check Report": "构建亲和",
                             "precision": "计算精度分析",
                             "UTgen": "UTgen"}
        report_type = {"64-bit Running Mode Check Report": "亲和扫描工具", "Static Check Report": "亲和扫描工具",
                       "Vectorization Check Report": "亲和扫描工具", "Build Affinity Check Report": "亲和扫描工具",
                       "Software Porting Assessment Report": "迁移扫描工具",
                       "Byte Alignment Check Report": "亲和扫描工具",
                       "Source Code Porting Report": "迁移扫描工具", "Compatibility_Application": "DevKit测试平台"
                       }
        print("The decompression is complete.")
        print("Scanning the report of the devkit-pipeline tool for pipeline construction...")
        source_path = ""
        acceptance_html_list = list()
        scan_report_info = [{'label': '门禁工具', 'value': '迁移扫描工具'}]
        core_report_info = [{'label': '门禁工具', 'value': '亲和扫描工具'}, {'label': '源码路径', 'value': ''},
                            {'label': '评估结果', 'value': '不通过'}]
        test_report_info = [{'label': '门禁工具', 'value': 'DevKit测试平台'}, {'label': '测试应用', 'value': ''},
                            {'label': '评估结果', 'value': '通过'}]
        tuner_report_info = [{'label': '门禁工具', 'value': '调优工具'},
                             {'label': '评估结果', 'value': '不通过'}]
        jdk_report_info = [{'label': '门禁工具', 'value': '毕昇JDK'},
                           {'label': '评估结果', 'value': '不通过'}]
        gcc_report_info = [{'label': '门禁工具', 'value': 'GCC for openEuler'},
                           {'label': '评估结果', 'value': '不通过'}]
        ut_report_info = [{'label': 'Java测试用例', 'value': 'UTgen'},
                          {'label': '评估结果', 'value': '不通过'}]
        test_devkit = ["Compatibility_Application_Start", "Compatibility_Application_Stop",
                       "Compatibility_Hardware_Server",
                       "Compatibility_Idle_Cpu", "Compatibility_Idle_Disk", "Compatibility_Idle_Memory",
                       "Compatibility_Idle_Network",
                       "Compatibility_Software_Name", "Reliability_Exception_Kill", "Reliability_Pressure_Cpu"]
        scan_report_detail = list()
        core_report_detail = list()
        test_report_detail = list()
        jdk_report_detail = list()
        gcc_report_detail = list()
        tuner_report_detail = list()
        ut_report_detail = list()
        scan_report_num = 0
        core_report_num = 0
        tuner_report_num = 0
        ut_report_num = 0
        for file in file_names:
            if file.endswith(".log"):
                with open(os.path.join(current_path, file), encoding='utf-8') as f:
                    content_all = f.read()
                if "Recover backup file" in content_all:
                    core_report_num += 1
                    core_report_detail.append([core_report_num, "计算精度分析",
                                               os.path.join(current_path, file), "使用"])
                    core_report_info[1]["value"] = source_path if not scan_report_info[0][
                        "value"] else source_path
                    core_report_info[2]["value"] = "通过"
            if file.endswith(".html"):
                try:
                    with open(os.path.join(current_path, file), encoding='utf-8') as f:
                        content_all = f.read()
                        f.seek(0)
                        content = f.readlines()
                except UnicodeDecodeError:
                    with open(os.path.join(current_path, file), encoding='gbk') as f:
                        content = f.readlines()
                        f.seek(0)
                        content_all = f.read()

                for acceptance_html in command_line_html.keys():
                    if acceptance_html in content_all:
                        acceptance_html_list.append(acceptance_html)
                        if acceptance_html != "Compatibility_Application":
                            flag = 0
                            for html_line in content:
                                if "Source File Path" in html_line and acceptance_html != "Software Porting Assessment Report":
                                    flag += 1
                                    continue
                                elif "Software Package Path or Name" in html_line:
                                    flag += 1
                                    continue
                                if flag == 1:
                                    source_path = \
                                        html_line.replace("""<span class="info">""", "").replace("""</span>""",
                                                                                                 "").strip()
                                    break

                        else:
                            for html_line in content:
                                if "Compatibility_Application_Start" in html_line:
                                    if html_line.find("7528") != -1:
                                        str1 = html_line.find("7528")
                                        str2 = html_line.find("542f")
                                        source_path = html_line[str1 + 3 + 1: str2 - 2]
                                if "git_tb_data" in html_line:
                                    html_line = html_line.replace("git_tb_data: [", "[").replace("],", "]").replace(
                                        "null", "None")
                                    html_line = eval(html_line)
                                    for line_content in html_line:
                                        if line_content in test_devkit:
                                            content_value = html_line[html_line.index(line_content) + 1]
                                            if content_value is None:
                                                content_value = ""
                                            test_report_detail.append([line_content, content_value])
                        if report_type.get(acceptance_html) == "迁移扫描工具":
                            scan_report_num += 1
                            scan_report_detail.append([scan_report_num, command_line_html.get(acceptance_html),
                                                       os.path.join(current_path, file), "使用"])
                            if command_line_html.get(acceptance_html) == "软件迁移评估":
                                if '软件包路径' not in str(scan_report_info):
                                    scan_report_info.append({'label': '软件包路径', 'value': source_path})
                            if command_line_html.get(acceptance_html) == "源码迁移":
                                if '源码路径' not in str(scan_report_info):
                                    scan_report_info.append({'label': '源码路径', 'value': source_path})

                        elif report_type.get(acceptance_html) == "亲和扫描工具":
                            core_report_num += 1
                            core_report_detail.append([core_report_num, command_line_html.get(acceptance_html),
                                                       os.path.join(current_path, file), "使用"])
                            core_report_info[1]["value"] = source_path if not scan_report_info[0][
                                "value"] else source_path
                            core_report_info[2]["value"] = "通过"
                        else:
                            test_report_info[1]["value"] = source_path
                            for detail in test_report_detail:
                                if detail[0] in ["Compatibility_Application_Start", "Compatibility_Application_Stop",
                                                 "Compatibility_Hardware_Server", "Compatibility_Software_Name"] and \
                                        detail[1] in ("failed", "", "skipped", None):
                                    test_report_info[2]["value"] = "不通过"

            elif file.endswith(".txt"):
                with open(os.path.join(current_path, file), encoding='utf-8') as f:
                    content_all = f.read()
                    f.seek(0)
                    gcc_contents = f.readlines()
                    f.seek(0)
                    jdk_content = f.readline()
                    if "BiSheng" in content_all or "Bisheng" in content_all:
                        jdk_report_info[1]["value"] = "通过"
                        jdk_report_detail = [[1, jdk_content, "使用"]]
                    for gcc_content in gcc_contents:
                        if "gcc version" in gcc_content:
                            if gcc_content.split(" ")[2].split(".")[2] == "1":
                                gcc_report_info[1]["value"] = "通过"
                                gcc_report_detail = [[1, gcc_content, "使用"]]
                        if "7.3.0" in gcc_content and "-mtune=tsv110" in content_all:
                            gcc_report_info[1]["value"] = "通过"
                            gcc_report_detail = [[1, gcc_content, "使用"]]
            elif file.endswith(".data"):
                tuner_report_num += 1
                # 定义要执行的命令
                command = ['perf', 'script', '-i', os.path.join(current_path, file)]
                try:
                    # 使用subprocess.run执行命令，并捕获输出
                    result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                    # 输出结果
                    res = result.stdout.decode()
                    if "libkperf" in res or "libsym" in res:
                        tuner_report_detail.append([tuner_report_num, "libkperf",
                                                    os.path.join(current_path, file), "使用"])
                        tuner_report_info[1]["value"] = "通过"
                    else:
                        tuner_report_detail.append([tuner_report_num, "libkperf",
                                                    os.path.join(current_path, file), "未使用"])
                except subprocess.CalledProcessError as e:
                    pass
            elif file.endswith(".java"):
                ut_report_num += 1
                with open(os.path.join(current_path, file), encoding='utf-8') as f:
                    content_all = f.read()
                if "UTgen" in content_all:
                    ut_report_detail.append([ut_report_num, "UTgen",
                                             os.path.join(current_path, file), "使用"])
                    ut_report_info[1]["value"] = "通过"
                else:
                    ut_report_info.append([ut_report_num, "UTgen",
                                           os.path.join(current_path, file), "未使用"])

        scan_report_flag = 0
        for scan_report in scan_report_info:
            if scan_report.get("label") in ('软件包路径', '源码路径'):
                scan_report_flag = 1
                if scan_report.get("value") and "评估结果" not in str(scan_report_info):
                    scan_report_info.append({'label': '评估结果', 'value': '通过'})
        if not scan_report_flag:
            scan_report_info.extend([{'label': '源码路径', 'value': ''}, {'label': '评估结果', 'value': '不通过'}])
        results = set(command_line_html.keys()) - set(acceptance_html_list)
        for result in results:
            if report_type.get(result) == "迁移扫描工具":
                scan_report_num += 1
                scan_report_detail.append([scan_report_num, command_line_html.get(result),
                                           "不存在", "未使用"])
            elif report_type.get(result) == "亲和扫描工具":
                core_report_num += 1
                core_report_detail.append([core_report_num, command_line_html.get(result),
                                           "不存在", "未使用"])
        if "精度分析" not in str(core_report_detail):
            core_report_num += 1
            core_report_detail.append([core_report_num, "精度分析",
                                       "不存在", "未使用"])
        if not tuner_report_detail:
            tuner_report_detail.append([1, "libkperf", "不存在", "未使用"])

        originals = """
                <html>
                <head>
                <meta charset="utf-8"/>
                <meta content="IE=edge" http-equiv="X-UA-Compatible"/>
                <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
                <title>Document</title>
                </head>
                <body>
                <div class="header">
                      DevKit验收报告
                    </div>
                <div class="content">
                <div class="title">
                        配置信息
                      </div>
                <div class="info">
                <div class="left">
                <div class="left-content">
                </div>
                </div>
                <div class="right">
                <div class="text"></div>
                <div class="num"></div>
                </div>
                </div>
                <div class="table">
                <div class="title">验收详细结果</div>
                <table>
                <tr>
                <th>序号</th>
                <th>使用工具</th>
                <th>报告路径</th>
                <th>使用状态</th>
                </tr>
                </table>
                </div>
                </div>
                </body>
                <script>    
                            var infoList = {};

                            // 已使能特性
                            var num = "";

                            // 验收详细结果
                            var tableList = {};




                    // 配置信息
                    var leftContentEle = document.getElementsByClassName('left-content')[0];
                    infoList.forEach(item => {{
                      let singleEle = document.createElement('div');
                      singleEle.setAttribute('class', 'single');
                      let labelEle = document.createElement('div');
                      labelEle.setAttribute('class', 'label');
                      labelEle.innerText = item.label;
                      let valueEle = document.createElement('div');
                      valueEle.setAttribute('class', 'value');
                      valueEle.innerText = item.value;

                      singleEle.appendChild(labelEle);
                      singleEle.appendChild(valueEle);
                      leftContentEle.appendChild(singleEle);
                    }})


                    // 已使能特性
                    var numEle = document.getElementsByClassName('num')[0];
                    numEle.innerText = num;


                    // 验收详细结果
                    var tableEle = document.getElementsByTagName('table')[0];
                    tableList.forEach(list => {{
                      let trEle = document.createElement('tr');
                      list.forEach(item => {{
                        let tdEle = document.createElement('td');
                        tdEle.innerText = item;
                        trEle.appendChild(tdEle);
                      }})
                      tableEle.appendChild(trEle);
                    }})


                  </script>
                <style>
                    body {{
                      background-color: #222020;
                      color: #fff;
                      padding: 8px 16px;
                      margin: 0;
                      font-size: 14px;
                    }}
                    .header {{
                      font-size: 18px;
                      width: 100%;
                      line-height: 50px;
                      border-bottom: 1px solid rgb(110, 110, 110);
                    }}
                    .info {{
                      display: flex;
                      justify-content: flex-start;
                      align-items: flex-start;
                    }}
                    .left {{
                      width: 60%;
                    }}
                    .title {{
                      font-size: 16px;
                      margin: 20px 0 10px 0;
                    }}
                    .single {{
                      display: flex;
                      justify-content: flex-start;
                      align-items: center;
                      margin: 8px 0;
                    }}
                    .label {{
                      color: rgb(195, 206, 216);
                      width: 30%;
                    }}
                    .right {{
                      width: 40%;
                      text-align: center;
                    }}
                    .text {{
                      font-size: 20px;
                      color: rgb(195, 206, 216);
                    }}
                    .num {{
                      font-size: 50px;
                    }}
                    table {{
                      border: 1px solid rgb(110, 110, 110);
                      width: 100%
                    }}
                    th{{
                      font-size: 14px; 
                      padding: 5px 15px;
                      color: rgb(222, 227, 231);
                      background-color: #555353;
                    }}
                    td {{
                      padding: 2px 5px;
                      border-top: 1px solid rgb(110, 110, 110);
                      border-right: 1px solid rgb(110, 110, 110);
                    }}
                    td:last-child {{
                      border-right: none
                    }}
                  </style>
                </html>"""
        test_originals = """
                        <html>
                        <head>
                        <meta charset="utf-8"/>
                        <meta content="IE=edge" http-equiv="X-UA-Compatible"/>
                        <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
                        <title>Document</title>
                        </head>
                        <body>
                        <div class="header">
                              DevKit验收报告
                            </div>
                        <div class="content">
                        <div class="title">
                                配置信息
                              </div>
                        <div class="info">
                        <div class="left">
                        <div class="left-content">
                        </div>
                        </div>
                        <div class="right">
                        <div class="text"></div>
                        <div class="num"></div>
                        </div>
                        </div>
                        <div class="table">
                        <div class="title">验收详细结果</div>
                        <table>
                        <tr>
                        <th>测试用例名称</th>
                        <th>测试用例结果</th>
                        </tr>
                        </table>
                        </div>
                        </div>
                        </body>
                        <script>    
                                    var infoList = {};

                                    // 已使能特性
                                    var num = "";

                                    // 验收详细结果
                                    var tableList = {};




                            // 配置信息
                            var leftContentEle = document.getElementsByClassName('left-content')[0];
                            infoList.forEach(item => {{
                              let singleEle = document.createElement('div');
                              singleEle.setAttribute('class', 'single');
                              let labelEle = document.createElement('div');
                              labelEle.setAttribute('class', 'label');
                              labelEle.innerText = item.label;
                              let valueEle = document.createElement('div');
                              valueEle.setAttribute('class', 'value');
                              valueEle.innerText = item.value;

                              singleEle.appendChild(labelEle);
                              singleEle.appendChild(valueEle);
                              leftContentEle.appendChild(singleEle);
                            }})


                            // 已使能特性
                            var numEle = document.getElementsByClassName('num')[0];
                            numEle.innerText = num;


                            // 验收详细结果
                            var tableEle = document.getElementsByTagName('table')[0];
                            tableList.forEach(list => {{
                              let trEle = document.createElement('tr');
                              list.forEach(item => {{
                                let tdEle = document.createElement('td');
                                tdEle.innerText = item;
                                trEle.appendChild(tdEle);
                              }})
                              tableEle.appendChild(trEle);
                            }})


                          </script>
                        <style>
                            body {{
                              background-color: #222020;
                              color: #fff;
                              padding: 8px 16px;
                              margin: 0;
                              font-size: 14px;
                            }}
                            .header {{
                              font-size: 18px;
                              width: 100%;
                              line-height: 50px;
                              border-bottom: 1px solid rgb(110, 110, 110);
                            }}
                            .info {{
                              display: flex;
                              justify-content: flex-start;
                              align-items: flex-start;
                            }}
                            .left {{
                              width: 60%;
                            }}
                            .title {{
                              font-size: 16px;
                              margin: 20px 0 10px 0;
                            }}
                            .single {{
                              display: flex;
                              justify-content: flex-start;
                              align-items: center;
                              margin: 8px 0;
                            }}
                            .label {{
                              color: rgb(195, 206, 216);
                              width: 30%;
                            }}
                            .right {{
                              width: 40%;
                              text-align: center;
                            }}
                            .text {{
                              font-size: 20px;
                              color: rgb(195, 206, 216);
                            }}
                            .num {{
                              font-size: 50px;
                            }}
                            table {{
                              border: 1px solid rgb(110, 110, 110);
                              width: 100%
                            }}
                            th{{
                              font-size: 14px; 
                              padding: 5px 15px;
                              color: rgb(222, 227, 231);
                              background-color: #555353;
                            }}
                            td {{
                              padding: 2px 5px;
                              border-top: 1px solid rgb(110, 110, 110);
                              border-right: 1px solid rgb(110, 110, 110);
                            }}
                            td:last-child {{
                              border-right: none
                            }}
                          </style>
                        </html>"""
        jdk_gcc_originals = """
                <html>
                <head>
                <meta charset="utf-8"/>
                <meta content="IE=edge" http-equiv="X-UA-Compatible"/>
                <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
                <title>Document</title>
                </head>
                <body>
                <div class="header">
                      DevKit验收报告
                    </div>
                <div class="content">
                <div class="title">
                        配置信息
                      </div>
                <div class="info">
                <div class="left">
                <div class="left-content">
                </div>
                </div>
                <div class="right">
                <div class="text"></div>
                <div class="num"></div>
                </div>
                </div>
                <div class="table">
                <div class="title">验收详细结果</div>
                <table>
                <tr>
                <th>序号</th>
                <th>使用工具</th>
                <th>使用状态</th>
                </tr>
                </table>
                </div>
                </div>
                </body>
                <script>    
                            var infoList = {};

                            // 已使能特性
                            var num = "";

                            // 验收详细结果
                            var tableList = {};




                    // 配置信息
                    var leftContentEle = document.getElementsByClassName('left-content')[0];
                    infoList.forEach(item => {{
                      let singleEle = document.createElement('div');
                      singleEle.setAttribute('class', 'single');
                      let labelEle = document.createElement('div');
                      labelEle.setAttribute('class', 'label');
                      labelEle.innerText = item.label;
                      let valueEle = document.createElement('div');
                      valueEle.setAttribute('class', 'value');
                      valueEle.innerText = item.value;

                      singleEle.appendChild(labelEle);
                      singleEle.appendChild(valueEle);
                      leftContentEle.appendChild(singleEle);
                    }})


                    // 已使能特性
                    var numEle = document.getElementsByClassName('num')[0];
                    numEle.innerText = num;


                    // 验收详细结果
                    var tableEle = document.getElementsByTagName('table')[0];
                    tableList.forEach(list => {{
                      let trEle = document.createElement('tr');
                      list.forEach(item => {{
                        let tdEle = document.createElement('td');
                        tdEle.innerText = item;
                        trEle.appendChild(tdEle);
                      }})
                      tableEle.appendChild(trEle);
                    }})


                  </script>
                <style>
                    body {{
                      background-color: #222020;
                      color: #fff;
                      padding: 8px 16px;
                      margin: 0;
                      font-size: 14px;
                    }}
                    .header {{
                      font-size: 18px;
                      width: 100%;
                      line-height: 50px;
                      border-bottom: 1px solid rgb(110, 110, 110);
                    }}
                    .info {{
                      display: flex;
                      justify-content: flex-start;
                      align-items: flex-start;
                    }}
                    .left {{
                      width: 60%;
                    }}
                    .title {{
                      font-size: 16px;
                      margin: 20px 0 10px 0;
                    }}
                    .single {{
                      display: flex;
                      justify-content: flex-start;
                      align-items: center;
                      margin: 8px 0;
                    }}
                    .label {{
                      color: rgb(195, 206, 216);
                      width: 30%;
                    }}
                    .right {{
                      width: 40%;
                      text-align: center;
                    }}
                    .text {{
                      font-size: 20px;
                      color: rgb(195, 206, 216);
                    }}
                    .num {{
                      font-size: 50px;
                    }}
                    table {{
                      border: 1px solid rgb(110, 110, 110);
                      width: 100%
                    }}
                    th{{
                      font-size: 14px; 
                      padding: 5px 15px;
                      color: rgb(222, 227, 231);
                      background-color: #555353;
                    }}
                    td {{
                      padding: 2px 5px;
                      border-top: 1px solid rgb(110, 110, 110);
                      border-right: 1px solid rgb(110, 110, 110);
                    }}
                    td:last-child {{
                      border-right: none
                    }}
                  </style>
                </html>"""
        scan_report_html = originals.format(scan_report_info, scan_report_detail)
        core_report_html = originals.format(core_report_info, core_report_detail)
        tuner_report_html = originals.format(tuner_report_info, tuner_report_detail)
        test_report_html = test_originals.format(test_report_info, test_report_detail)
        jdk_report_html = jdk_gcc_originals.format(jdk_report_info, jdk_report_detail)
        gcc_report_html = jdk_gcc_originals.format(gcc_report_info, gcc_report_detail)
        ut_report_html = originals.format(ut_report_info, ut_report_detail)
        with open(os.path.join(current_path, "迁移扫描工具.html"), "w", encoding="utf-8") as f:
            f.write(scan_report_html)
        with open(os.path.join(current_path, "亲和扫描工具.html"), "w", encoding="utf-8") as f:
            f.write(core_report_html)
        with open(os.path.join(current_path, "DevKit测试平台.html"), "w", encoding="utf-8") as f:
            f.write(test_report_html)
        # with open(os.path.join(current_path, "毕昇JDK.html"), "w", encoding="utf-8") as f:
        #     f.write(jdk_report_html)
        # with open(os.path.join(current_path, "GCC for openEuler.html"), "w", encoding="utf-8") as f:
        #     f.write(gcc_report_html)
        with open(os.path.join(current_path, "调优工具.html"), "w", encoding="utf-8") as f:
            f.write(tuner_report_html)
        with open(os.path.join(current_path, "UTgen.html"), "w", encoding="utf-8") as f:
            f.write(ut_report_html)
        print("Decompression completed. View the report in {}.".format(current_path))


def decompress_zip(compressed_report_package, file_list=[]):
    with zipfile.ZipFile(compressed_report_package, 'r') as zip:
        zip.extractall("./")
        for file in zip.namelist():
            if file.endswith('.zip'):
                decompress_zip(file)
    file_names = zip.namelist()
    file_list.extend(file_names)
    return file_list


def decompress_gz_bz(compressed_report_package):
    file_list = []
    with tarfile.open(compressed_report_package, "r") as tar:
        tar.extractall(path="./")
        file_names = tar.getnames()
        for file in file_names:
            if file.endswith('.zip'):
                decompress_zip(file, file_list=file_list)
        file_list.extend(file_names)
        return file_list


if __name__ == "__main__":
    try:
        parser = argparse.ArgumentParser()
        parser.add_argument('-tool', help='DevKit or BoostKit')
        parser.add_argument('-package', help='Compressed package')
        args = parser.parse_args()
        acceptance_tool = AcceptanceTool()
        if args.tool == "DevKit":
            acceptance_tool.devkit_acceptance_report(args.package)
        elif args.tool == "BoostKit":
            pass
        else:
            print("Enter a correct parameter, for example, -tool DevKit or -tool BoostKit.")

    except Exception as err:
        print(err)
        print("Enter a correct parameter.")
